﻿namespace State.Pattern
{
    public interface ITurnstileState
    {
        void Coin(Turnstile t);
        void Pass(Turnstile t);
    }

    public interface ITurnstileController
    {
        void Lock();
        void Unlock();
        void Thankyou();
        void Alarm();
    }

    internal class LockedTurnstileState : ITurnstileState
    {
        public void Coin(Turnstile t)
        {
            t.SetUnlocked();
            t.Unlock();
        }
        public void Pass(Turnstile t)
        {
            t.Alarm();
        }
    }

    internal class UnlockedTurnstileState : ITurnstileState
    {
        public void Coin(Turnstile t)
        {
            t.Thankyou();
        }

        public void Pass(Turnstile t)
        {
            t.SetLocked();
            t.Lock();
        }
    }

    public class Turnstile
    {
        internal static ITurnstileState lockedState = new LockedTurnstileState();

        internal static ITurnstileState unlockedState = new UnlockedTurnstileState();

        private ITurnstileController turnstileController;

        internal ITurnstileState state = unlockedState;

        public Turnstile(ITurnstileController action)
        {
            turnstileController = action;
        }

        public void Coin()
        {
            state.Coin(this);
        }

        public void Pass()
        {
            state.Pass(this);
        }

        public void SetLocked()
        {
            state = lockedState;
        }

        public void SetUnlocked()
        {
            state = unlockedState;
        }

        public bool IsLocked()
        {
            return state == lockedState;
        }

        public bool IsUnlocked()
        {
            return state == unlockedState;
        }

        internal void Thankyou()
        {
            turnstileController.Thankyou();
        }

        internal void Alarm()
        {
            turnstileController.Alarm();
        }

        internal void Lock()
        {
            turnstileController.Lock();
        }

        internal void Unlock()
        {
            turnstileController.Unlock();
        }
    }
}
